home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / GRAHAM / XAAES_S.ZIP / XAAES / C_WINDOW.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-06  |  12.8 KB  |  556 lines

  1. /*
  2.  * XaAES - XaAES Ain't the AES
  3.  *
  4.  * A multitasking AES replacement for MiNT
  5.  *
  6.  */
  7.  
  8. #include <VDI.H>
  9. #include <MINTBIND.H>
  10. #include <memory.h>
  11. #include "XA_TYPES.H"
  12. #include "XA_DEFS.H"
  13. #include "XA_GLOBL.H"
  14. #include "STD_WIDG.H"
  15. #include "BOX3D.H"
  16. #include "C_WINDOW.H"
  17. #include "RECTLIST.H"
  18. #include "MESSAGES.H"
  19. #include "OBJECTS.H"
  20. #include "RESOURCE.H"
  21. #include "SYSTEM.H"
  22. #include "DESKTOP.H"
  23.  
  24. /*
  25.     Low-level Window Stack Management Functions
  26. */
  27.  
  28. XA_WINDOW *window_list=NULL;        /* The global system window stack */
  29. short wind_handle=0;                /* Window handle counter (used to generate unique window handles)
  30.                                        As this loops round, there may be a problem if a user opens
  31.                                        more than 32767 windows in one session :) */
  32.  
  33. /*
  34.      Create a window
  35. */
  36. XA_WINDOW *create_window(short pid, long tp, short rx, short ry, short rw, short rh)
  37. {
  38.     XA_WINDOW *nw=(XA_WINDOW *)malloc(sizeof(XA_WINDOW));
  39.  
  40.     if (!nw)            /* Unable to allocate memory for window? */
  41.         return NULL;
  42.  
  43.     nw->x=rx;
  44.     nw->y=ry;
  45.     nw->w=rw;
  46.     nw->h=rh;
  47.     nw->prev_x=rx;
  48.     nw->prev_y=ry;
  49.     nw->prev_w=rw;
  50.     nw->prev_h=rh;
  51.     nw->handle=wind_handle++;
  52.     nw->owner=pid;
  53.     nw->is_open=FALSE;
  54. #if JOHAN_RECTANGLES
  55.     nw->rl_full = NULL;
  56.     nw->rl_work = NULL;
  57. #else
  58.     nw->rect_list=NULL;
  59. #endif
  60.     nw->redraw=NULL;
  61.     nw->keypress=NULL;
  62.     nw->window_status=XAWS_CLOSED;
  63.     
  64.     Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  65.     
  66.     if (root_window)    /* Append window to back of window list, behind the root window (if it exists) */
  67.     {
  68.         nw->prev=root_window;
  69.         nw->next=root_window->next;
  70.         if (root_window->next)
  71.             root_window->next->prev=nw;
  72.         root_window->next=nw;
  73.     }else{
  74.         nw->next=NULL;
  75.         nw->prev=NULL;
  76.         window_list=nw;
  77.     }
  78.     
  79.     Psemaphore(3,WIN_LIST_SEMAPHORE,0);
  80.     
  81.     standard_widgets(nw,tp);    /* Attatch the appropriate widgets to the window */
  82.  
  83.     if (tp&STORE_BACK)            /* If STORE_BACK extended attribute is used, window preserves it's own background */
  84.     {
  85.         nw->background=(void*)malloc(display.planes*((rw+35)>>2)*(rh+20));
  86.         nw->bgx=-1;
  87.     }else{
  88.         nw->background=NULL;
  89.     }
  90.     
  91.     calc_work_area(nw);            /* Calculate an initial work area */
  92.  
  93.     return nw;
  94. }
  95.  
  96. /*
  97.     Display a window
  98. */
  99. void display_window(XA_WINDOW *wind)
  100. {
  101.     short f,pnt[8],x,y,w,h;
  102.     WidgetCallback wc;
  103.  
  104.     if (wind->active_widgets&STORE_BACK)    /* Is this a 'preserve own background' window? */
  105.     {
  106.         MFDB Mscreen;
  107.         MFDB Mpreserve;
  108.         
  109.         pnt[0]=wind->x; pnt[1]=wind->y; pnt[2]=wind->x+wind->w; pnt[3]=wind->y+wind->h;
  110.         pnt[4]=0; pnt[5]=0; pnt[6]=wind->w; pnt[7]=wind->h;
  111.         
  112.         Mpreserve.fd_w=wind->w+20;
  113.         Mpreserve.fd_h=wind->h+20;
  114.         Mpreserve.fd_wdwidth=(Mpreserve.fd_w+15)>>4;
  115.         Mpreserve.fd_nplanes=display.planes;
  116.         Mpreserve.fd_stand=0;
  117.         Mpreserve.fd_addr=wind->background;
  118.  
  119.         Mscreen.fd_addr=NULL;
  120.  
  121.         v_hide_c(V_handle);
  122.         vro_cpyfm(V_handle, S_ONLY, pnt, &Mscreen, &Mpreserve);
  123.         v_show_c(V_handle,1);
  124.         
  125.         wind->bgx=wind->x; wind->bgy=wind->y;
  126.     }
  127.     
  128.     x=wind->wx;
  129.     y=wind->wy;
  130.     w=wind->ww;
  131.     h=wind->wh;
  132.     
  133. /* Display the window backdrop (borders only, GEM style) */
  134.     vsf_color(V_handle,display.dial_colours.bg_col);
  135.     vsf_interior(V_handle,FIS_SOLID);
  136.     pnt[0]=wind->x; pnt[1]=wind->y; pnt[2]=wind->x+wind->w-SHADOW_OFFSET; pnt[3]=y;
  137.     v_bar(V_handle,pnt);
  138.     pnt[1]=y+h; pnt[3]=wind->y+wind->h-SHADOW_OFFSET;
  139.     v_bar(V_handle,pnt);
  140.     pnt[0]=wind->x; pnt[1]=wind->y; pnt[2]=x;
  141.     v_bar(V_handle,pnt);
  142.     pnt[0]=x+w; pnt[2]=wind->x+wind->w-SHADOW_OFFSET;
  143.     v_bar(V_handle,pnt);
  144.  
  145. /* Display drop shadow  */
  146.     vsf_color(V_handle,display.dial_colours.border_col);
  147.     pnt[0]=wind->x+wind->w-SHADOW_OFFSET+1; pnt[1]=wind->y+SHADOW_OFFSET; pnt[2]=wind->x+wind->w; pnt[3]=wind->y+wind->h;
  148.     v_bar(V_handle,pnt);
  149.     pnt[0]=wind->x+SHADOW_OFFSET; pnt[1]=wind->y+wind->h-SHADOW_OFFSET+1; pnt[2]=wind->x+wind->w-SHADOW_OFFSET; pnt[3]=wind->y+wind->h;
  150.     v_bar(V_handle,pnt);
  151.  
  152. /* Display the work area */
  153.     if (!(wind->active_widgets&NO_WORK))
  154.     {
  155.         vsl_color(V_handle,display.dial_colours.b_r_col);
  156.  
  157.         pnt[0]=x; pnt[1]=y+h;
  158.         pnt[2]=x; pnt[3]=y;
  159.         pnt[4]=x+w; pnt[5]=y;
  160.         v_pline(V_handle,3,pnt);
  161.     
  162.         pnt[0]=x+2; pnt[1]=y+h-1;
  163.         pnt[2]=x+w-1; pnt[3]=y+h-1;
  164.         pnt[4]=x+w-1; pnt[5]=y+1;
  165.         v_pline(V_handle,3,pnt);
  166.     
  167.         vsl_color(V_handle,display.dial_colours.t_l_col);
  168.  
  169.         pnt[0]=x+w; pnt[1]=y+1;
  170.         pnt[2]=x+w; pnt[3]=y+h;
  171.         pnt[4]=x+1; pnt[5]=y+h;
  172.         v_pline(V_handle,3,pnt);
  173.     
  174.         pnt[0]=x+1; pnt[1]=y+h-1;
  175.         pnt[2]=x+1; pnt[3]=y+1;
  176.         pnt[4]=x+w-1; pnt[5]=y+1;
  177.         v_pline(V_handle,3,pnt);
  178.     }
  179.  
  180. /* Go through and display the window widgets using their display behaviour */
  181.     if (wind->window_status==XAWS_ICONIFIED)
  182.     {
  183.         wc=wind->widgets[XAW_TITLE].behaviour[XACB_DISPLAY];
  184.         (*wc)(wind, &(wind->widgets[XAW_TITLE]));
  185.         wc=wind->widgets[XAW_ICONIFY].behaviour[XACB_DISPLAY];
  186.         (*wc)(wind, &(wind->widgets[XAW_ICONIFY]));
  187.     }else{
  188.         for(f=0; f<XA_MAX_WIDGETS; f++)
  189.         {
  190.             wc=wind->widgets[f].behaviour[XACB_DISPLAY];
  191.             if (wc)
  192.                 (*wc)(wind, &(wind->widgets[f]));
  193.         }
  194.     }
  195.  
  196. /* If the window has an auto-redraw function, call it */
  197.     if (wind->redraw)
  198.     {
  199.         (*(wind->redraw))(wind);
  200.     }
  201.  
  202. }
  203.  
  204. XA_WINDOW *wind_find(short x, short y)
  205. {
  206.     XA_WINDOW *w=window_list;
  207.  
  208.     Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  209.     
  210.     while(w)
  211.     {
  212.         if ((w->is_open)&&((((x>=w->x)&&(y>=w->y))&&(x<w->x+w->w))&&(y<w->y+w->h)))
  213.         {
  214.             Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  215.             return w;
  216.         }
  217.         w=w->next;
  218.     }
  219.     
  220.     Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  221.     
  222.     return NULL;
  223. }
  224.     
  225.  
  226. XA_WINDOW *get_wind_by_handle(short h)
  227. {
  228.     XA_WINDOW *w;
  229.  
  230.     Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  231.     
  232.     w=window_list;
  233.     
  234.     while(w)
  235.     {
  236.         if (w->handle==h)
  237.         {
  238.             Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  239.             return w;
  240.         }
  241.         w=w->next;
  242.     }
  243.     
  244.     Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  245.     
  246.     return NULL;
  247. }
  248.  
  249. /*
  250.     Pull this window to the head of the window list
  251. */
  252. void pull_wind_to_top(XA_WINDOW *w)
  253. {
  254.     XA_CLIENT *owner;
  255.  
  256.     Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  257.  
  258.     if (window_list->owner!=w->owner)    /* If we're getting a new top window, we may need */
  259.     {                                    /* to swap menu bars..... */
  260.         XA_WIDGET_TREE *menu_bar;
  261.  
  262.         Psemaphore(2,ROOT_SEMAPHORE,-1L);
  263.  
  264.         menu_bar=(XA_WIDGET_TREE*)(root_window->widgets[XAW_MENU].stuff);
  265.  
  266.         owner=Pid2Client(w->owner);
  267.         menu_bar->tree=owner->std_menu;
  268.         menu_bar->owner=w->owner;
  269.  
  270.         if ((owner->desktop)                    /* Change desktops? */
  271.             &&((owner->desktop!=desktop)&&(owner->desktop!=ResourceTree(system_resources,DEF_DESKTOP))))
  272.         {
  273.             set_desktop(owner->desktop);
  274.             root_window->owner=w->owner;;
  275.  
  276.             v_hide_c(V_handle);
  277.             display_non_topped_window(root_window,NULL);
  278.             v_show_c(V_handle,1);
  279.         }else{                                            /* No - just change menu bars */
  280.             GRECT clip;
  281.  
  282.             rp_2_ap(root_window, root_window->widgets+XAW_MENU, &clip.g_x, &clip.g_y);
  283.  
  284.             clip.g_w=root_window->widgets[XAW_MENU].w;
  285.             clip.g_h=root_window->widgets[XAW_MENU].h;
  286.  
  287.             v_hide_c(V_handle);
  288.             display_non_topped_window(root_window,&clip);
  289.             v_show_c(V_handle,1);
  290.         }
  291.  
  292.         Psemaphore(3,ROOT_SEMAPHORE,0L);
  293.     }
  294.  
  295.     if (w->prev)
  296.     {
  297.         w->prev->next=w->next;
  298.     }else{
  299.         window_list=w->next;
  300.     }
  301.     if (w->next)
  302.         w->next->prev=w->prev;
  303.     w->next=window_list;
  304.     if (window_list) window_list->prev=w;
  305.     w->prev=NULL;
  306.     window_list=w;
  307.  
  308.     Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  309.  
  310. }
  311.  
  312. void send_wind_to_bottom(XA_WINDOW *w)
  313. {
  314.     XA_WINDOW *old_top=window_list;
  315.     
  316.     if (w->next==NULL) return;            /* Can't send to the bottom a window that's already there */
  317.     
  318.     Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  319.     
  320.     if (w==window_list)                    /* If this window was on top, change window list */
  321.         window_list=w->next;
  322.     
  323.     if (w->next)                        /* Remove window from window list */
  324.         w->next->prev=w->prev;
  325.     
  326.     if (w->prev)
  327.         w->prev->next=w->next;
  328.         
  329.     w->prev=root_window->prev;
  330.     w->next=root_window;
  331.     
  332.     if (w->prev)                        /* root window is always at the bottom */
  333.     {
  334.         w->prev->next=w;
  335.     }else{
  336.         window_list=w;                    /* window is still on top (must be the only window */
  337.     }
  338.  
  339.     root_window->prev=w;
  340.     
  341.     Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  342.  
  343.     if (window_list==old_top)            /* If no change in top window, we can return here */
  344.     {
  345.         return;
  346.     }
  347.     
  348.  
  349.     if (old_top->owner!=window_list->owner)    /* If we're getting a new top window, we may need */
  350.     {                                        /* to swap menu bars..... */
  351.         XA_WIDGET_TREE *menu_bar=(XA_WIDGET_TREE*)(root_window->widgets[XAW_MENU].stuff);
  352.         XA_CLIENT *owner;
  353.     
  354.         Psemaphore(2,ROOT_SEMAPHORE,-1L);
  355.             
  356.         owner=Pid2Client(window_list->owner);
  357.         menu_bar->tree=owner->std_menu;
  358.         menu_bar->owner=window_list->owner;
  359.  
  360.         if (owner->desktop                    /* Change desktops? */
  361.             &&((owner->desktop!=desktop)&&(owner->desktop!=ResourceTree(system_resources,DEF_DESKTOP))))
  362.         {
  363.             set_desktop(owner->desktop);
  364.             root_window->owner=window_list->owner;
  365.  
  366.             v_hide_c(V_handle);
  367.             display_non_topped_window(root_window,NULL);
  368.             v_show_c(V_handle,1);
  369.         }else{                                            /* No - just change menu bars */
  370.             GRECT clip;
  371.  
  372.             rp_2_ap(root_window, root_window->widgets+XAW_MENU, &clip.g_x, &clip.g_y);
  373.         
  374.             clip.g_w=root_window->widgets[XAW_MENU].w;
  375.             clip.g_h=root_window->widgets[XAW_MENU].h;
  376.  
  377.             v_hide_c(V_handle);
  378.             display_non_topped_window(root_window,&clip);
  379.             v_show_c(V_handle,1);
  380.         }
  381.  
  382.         Psemaphore(3,ROOT_SEMAPHORE,0L);
  383.     }
  384. }
  385.  
  386. void delete_window(XA_WINDOW *wind)
  387. {
  388.     if (!wind) return;
  389.  
  390.     Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  391.     
  392.     if (wind==window_list)
  393.         window_list=wind->next;
  394.  
  395.     if (wind->prev) wind->prev->next=wind->next;
  396.     if (wind->next) wind->next->prev=wind->prev;
  397.  
  398.     if (wind->background)
  399.         free(wind->background);
  400.     
  401.     Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  402.  
  403.     free(wind);
  404. }
  405.  
  406. /*
  407.     Display a window that isn't on top, respecting clipping
  408.     - pass clip==NULL to redraw whole window, otherwise clip is a pointer to a GRECT that
  409.     defines the clip rectangle.
  410. */
  411. void display_non_topped_window(XA_WINDOW *w,GRECT *clip)
  412. {
  413.     GRECT target;
  414. #if JOHAN_RECTANGLES
  415.     XA_RECT_LIST *rl, *drl;
  416. #else
  417.     XA_RECT_LIST *drl;
  418.     XA_RECT_LIST *rl=generate_rect_list(w);
  419. #endif
  420.  
  421. #if JOHAN_RECTANGLES
  422.     if (!(rl = w->rl_full))
  423.         rl = w->rl_full = generate_rect_list(w);
  424. #endif
  425.  
  426.  
  427.     if (w->is_open)
  428.     {
  429.         while(rl)
  430.         {
  431.             drl=rl;
  432.             
  433.             if (clip)
  434.             {
  435.                 target.g_x=rl->x;
  436.                 target.g_y=rl->y;
  437.                 target.g_w=rl->w;
  438.                 target.g_h=rl->h;
  439.                 
  440.                 if (rc_intersect(clip,&target))
  441.                 {
  442.                     set_clip(target.g_x, target.g_y, target.g_w, target.g_h);
  443.                     display_window(w);
  444.                 }
  445.             }else{
  446.                 set_clip(rl->x, rl->y, rl->w, rl->h);
  447.                 display_window(w);
  448.             }
  449.             rl=rl->next;
  450. #if JOHAN_RECTANGLES
  451. #else
  452.             free(drl);
  453. #endif
  454.         }
  455.     }
  456.     clear_clip();
  457. }
  458.  
  459. /*
  460.     Display all windows BELOW the current location of a window.
  461.     - this has the effect of erasing the window.
  462. */
  463. void display_windows_below(XA_WINDOW *w)
  464. {
  465.     GRECT old_r,win_r;
  466.     XA_WINDOW *wl;
  467.     XA_RECT_LIST *drl;
  468.     XA_RECT_LIST *rl;
  469.     short keep_is_open;
  470.  
  471.     keep_is_open=w->is_open;
  472.     w->is_open=FALSE;                    /* Flag this window as closed to allow rectangle list to
  473.                                            overwrite it */
  474.  
  475.     if (w->active_widgets&STORE_BACK)    /* Is this a 'preserve own background' window? */
  476.     {
  477.         MFDB Mscreen;
  478.         MFDB Mpreserve;
  479.         short pnt[8];
  480.     
  481.         if (window_list==w)
  482.             clear_clip();
  483.     
  484.         pnt[0]=0; pnt[1]=0; pnt[2]=w->w; pnt[3]=w->h;
  485.         pnt[4]=w->bgx; pnt[5]=w->bgy; pnt[6]=w->bgx+w->w; pnt[7]=w->bgy+w->h;
  486.     
  487.         Mpreserve.fd_w=w->w+20;
  488.         Mpreserve.fd_h=w->h+20;
  489.         Mpreserve.fd_wdwidth=(Mpreserve.fd_w+15)>>4;
  490.         Mpreserve.fd_nplanes=display.planes;
  491.         Mpreserve.fd_stand=0;
  492.         Mpreserve.fd_addr=w->background;
  493.         Mscreen.fd_addr=NULL;
  494.     
  495.         v_hide_c(V_handle);
  496.         vro_cpyfm(V_handle, S_ONLY, pnt, &Mpreserve, &Mscreen);
  497.         v_show_c(V_handle,1);
  498.     }else{
  499.         
  500.         if (w->next)    /* We only need to do this bit if there are any windows lower than window */
  501.         {    
  502.             old_r.g_x=w->x;
  503.             old_r.g_y=w->y;
  504.             old_r.g_w=w->w;
  505.             old_r.g_h=w->h;
  506.     
  507.             for(wl=root_window; wl!=w; wl=wl->prev)            /* Check for redraws of windows starting at the root*/
  508.             {                                                /* and working up to our window, and redraw using */
  509.                                                             /* intersections with the rectangle of our window. */
  510.                 if (wl->is_open)
  511.                 {
  512. #if JOHAN_RECTANGLES
  513.                     if (!(rl = wl->rl_full))
  514.                         rl = wl->rl_full = generate_rect_list(wl);
  515. #else
  516.                     rl=generate_rect_list(wl);
  517. #endif
  518.                     while(rl)
  519.                     {
  520.                     
  521.                         win_r.g_x=rl->x;
  522.                         win_r.g_y=rl->y;
  523.                         win_r.g_w=rl->w;
  524.                         win_r.g_h=rl->h;
  525.                     
  526.                         if (rc_intersect(&old_r, &win_r))
  527.                         {
  528.                             set_clip(win_r.g_x, win_r.g_y, win_r.g_w, win_r.g_h);
  529.  
  530.                             display_window(wl);                /* Display the window */
  531.                             
  532.                                             /* send a redraw message to the owner of the window for this rectangle */
  533.                             if (!(wl->active_widgets&NO_REDRAWS))
  534.                                 send_app_message(wl->owner, WM_REDRAW, 0, wl->handle, win_r.g_x, win_r.g_y, win_r.g_w, win_r.g_h);
  535.                         }
  536.                         
  537.                         drl=rl;
  538.                         rl=rl->next;
  539. #if JOHAN_RECTANGLES
  540. #else
  541.                         free(drl);
  542. #endif
  543.                     }
  544.                 }
  545.             
  546.             }
  547.         
  548.         }
  549.     }
  550.     
  551.     clear_clip();
  552.  
  553.     w->is_open=keep_is_open;
  554.  
  555. }
  556.